#define N 5   //哲学家个数
void philosopher(int i) //哲学家个数 0-4
{
	while(1)  //去拿两把叉子
	{
		take_fork(i);  //去拿左边的叉子
		if(fork((i+1)%N))  //右边的叉子还在吗
		{
			take_fork((i+1)%N);  //去拿右边的叉子
			break;               //两把叉子均到手
		}
		else            //右边叉子已不在
		{
			put_fork(i);  //放下左边的叉子
			wait_some_time(); //等待一会儿（等待同样时间会同时拿起，同时放下）
			//wait_random_time()  随机时间也存在问题，但优于同样时间。不能确保完全正确
		}
	}
}

思路（1）哲学家自己怎么来解决这个问题？
指导原则：要么不拿，要么就拿两把叉子
S1 思考中...
S2 进入饥饿状态;
S3 如果左邻居或右邻居正在进餐，等待；否则转S4
S4 拿起两把叉子；
S5 吃面条...
S6 放下左边的叉子；
S7 放下右边的叉子；
S8 新的循环又开始了，转S1

思路（2）计算机程序怎么来解决这个问题？
指导原则：不能浪费CPU时间；进程间相互通信。
S1 思考中...
S2 进入饥饿状态；
S3 如果左邻居或者右邻居正在进餐，进程进入阻塞状态；否则转S4
S4 拿起两把叉子；
S5 吃面条...
S6 放下左边的叉子，看看左邻居现在能否进餐（饥饿状态，两把叉子都在），若能则唤醒之；
S7 放下右边的叉子，看看右邻居现在能否进餐，（饥饿状态，两把叉子都在），若能，唤醒之；
S8 新的一天开始了，转S1

思路（3）怎么样来编写程序？
1. 必须有数据结构，来描述每个哲学家的当前状态；
#define N 5            //哲学家个数
#define LEFT i         //第i个哲学家的左邻居
#define RIGHT (i+1)%N  //第i个哲学家的右邻居
#define THINKING 0     //思考状态
#define HUNGRY   1     //饥饿状态
#define EATING   2     //进餐状态
int state[N];          //记录每个人的状态
2. 该状态是一个临界资源，各个哲学家对它的访问应该互斥地进行——进程互斥；
semaphore  mutex;      //互斥信号量，初值1
3. 一个哲学家吃饱后，可能要唤醒它的左邻右舍，两者之间存在着同步关系——进程同步；
semaphore  s[N];       //同步信号量，初始0
